# %% test speed function

import qca as qca
import numpy as np
import matplotlib.pyplot as plt
import imageio
import matplotlib.image as mpimg
from Chaikin import *
from scipy.signal import convolve2d
def testSpeedFunction():
    sigmoid_inputs = np.arange(0,170,0.01)

    sigmoid_outputs = []
    for p in sigmoid_inputs:
        sigmoid_outputs.append(qca.speed_function(p))
    print("Sigmoid Function Input :: {}".format(sigmoid_inputs))
    print("Sigmoid Function Output :: {}".format(sigmoid_outputs))

    plt.plot(sigmoid_inputs,sigmoid_outputs)
    plt.xlabel("Sigmoid Inputs")
    plt.ylabel("Sigmoid Outputs")
    plt.show()




#%%
# testdata1
def testInputData():
    img = mpimg.imread('../resource/angiogram.jpg')
    gray_img = np.dot(img[...,:3],[0.2989,0.5870,0.114])
    startPoint=[150,100]
    endPoint=[395,442]
    # testdata2
    # gray_img=imageio.imread('../resource/image.png')
    # startPoint=[163,152]
    # endPoint=[273,31]
    plt.scatter(startPoint[1],startPoint[0],s=1,c=[0,1,0])
    plt.scatter(endPoint[1],endPoint[0],s=1,c=[0,1,0])

    plt.imshow(gray_img)
    return gray_img,startPoint,endPoint
def testBifurcation():
    img = mpimg.imread('../resource/angiogram.jpg')
    gray_img = np.dot(img[...,:3],[0.2989,0.5870,0.114])
    startPoint=[331,257]
    endPoint1=[395,431]
    endPoint2=[463,398]
    plt.scatter(startPoint[1],startPoint[0],s=1,c=[0,1,0])
    plt.scatter(endPoint1[1],endPoint1[0],s=1,c=[0,1,0])
    plt.scatter(endPoint2[1],endPoint2[0],s=1,c=[0,1,0])

    plt.imshow(gray_img)
    return gray_img,startPoint,endPoint1,endPoint2
def pltPerpendicularLines(perpendicularLines,img):
    for p in perpendicularLines[::4]:
        # print(p)
        p0=p[0]+p[1]*40
        p1=p[0]-p[1]*40
        # print(p0,p1)
        plt.plot([p0[1],p1[1]],[p0[0],p1[0]],c=(0,1,0))
        # break
    plt.scatter(np.array(perpendicularLines)[:,0,1],np.array(perpendicularLines)[:,0,0],s=1,c=(1,1,1))
    plt.imshow(img)

def pltLines(perpendicularLines,lines,img):


    plt.figure(figsize=(10,10))
    if perpendicularLines:
        pltPerpendicularLines(perpendicularLines,img)

    for smoothp1 in lines:
        plt.scatter([p.y for p in smoothp1],[p.x for p in smoothp1],s=1,c=[0,1,0])

    plt.imshow(img,cmap='gray')



def mca(gray_img,path,smoothStep=15):
    perpendicularLines,strengthValue,resampledImg,convolve2dimage1st,convolve2dimage2st = qca.edgeStrength(gray_img,path,20,40)
    shape = strengthValue.shape
    path1 = qca.dynamic_programming(strengthValue[:,0:int(shape[1]/2),0])
    path2 = qca.dynamic_programming(-strengthValue[:,int(shape[1]/2):,0])
    countour1=qca.mapCountour2img(strengthValue[:,0:int(shape[1]/2),:],path1)
    countour2=qca.mapCountour2img(strengthValue[:,int(shape[1]/2):,:],path2)
    points=[]
    for p in countour1[::smoothStep]:
        points.append(PointD(p[0],p[1]))
    points.append(PointD(countour1[-1][0],countour1[-1][1]))
    smoothed_points = chaikin_smoothing(points, tension=0.5, nr_of_iterations=3)
    points=[]
    for p in countour2[::smoothStep]:
        points.append(PointD(p[0],p[1]))
    points.append(PointD(countour2[-1][0],countour2[-1][1]))
    
    smoothed_points2 = chaikin_smoothing(points, tension=0.5, nr_of_iterations=3)
    return smoothed_points,smoothed_points2,perpendicularLines


#%%
def _main_():
    pass
    #%%
    gray_img,startPoint,endPoint = testInputData()
    # %%
    arrival_times = qca.wavefront_propagation(gray_img, (startPoint[0],startPoint[1]),(endPoint[0],endPoint[1]))
    plt.imshow(arrival_times)

    # %%
    
    path = qca.backtracking(arrival_times, (endPoint[0],endPoint[1]))
    plt.figure(figsize=(20,20))
    plt.scatter([p[1] for p in path],[p[0] for p in path],s=1,c=[0,1,0])
    plt.imshow(gray_img)

    # %% first
    smoothed_points,smoothed_points2,perpendicularLines =mca(gray_img,path,15)
    pltLines(perpendicularLines,[smoothed_points,smoothed_points2],gray_img)

    # %% second 
    newPath=[]
    for index in range(len(smoothed_points)):
        newPath.append(((smoothed_points[index].x+smoothed_points2[index].x)/2,(smoothed_points[index].y+smoothed_points2[index].y)/2))
    smoothp1,smoothp2,perpendicularLines = qca.mca(gray_img,newPath,8)
    pltLines(perpendicularLines,[smoothp1,smoothp2],gray_img)


############
    #%%
    gray_img,startPoint,endPoint1,endPoint2= testBifurcation()
    #%%
    arrival_times = qca.wavefront_propagation(gray_img, startPoint,endPoint1,endPoint2)
    path = qca.backtracking(arrival_times, (endPoint1[0],endPoint1[1]))
    # arrival_times2 = qca.wavefront_propagation(gray_img, startPoint,endPoint2)
    path2 = qca.backtracking(arrival_times, (endPoint2[0],endPoint2[1]))
    #%%
    proximalPath=[]
    distalPath1=[]
    distalPath2=[]
    for p in path:
        if p in path2:
            proximalPath.append(p)
        else:
            distalPath1.append(p)
    distalPath2 = path2[len(proximalPath):]

    plt.scatter([p[1] for p in proximalPath],[p[0] for p in proximalPath],s=1,c=[1,1,1])
    plt.scatter([p[1] for p in distalPath1],[p[0] for p in distalPath1],s=1,c=[0,1,0])
    plt.scatter([p[1] for p in distalPath2],[p[0] for p in distalPath2],s=1,c=[0,0,1])
    plt.imshow(gray_img)
    #%%

    smoothStep=15
    perpendicularLines1,strengthValue,resampledImg1,convolve2dimage1st1,convolve2dimage2st1 = qca.edgeStrength(gray_img,proximalPath+distalPath1,20,40)
    shape=strengthValue.shape
    path1 = qca.dynamic_programming(-strengthValue[:,int(shape[1]/2):,0])
    countour1=qca.mapCountour2img(strengthValue[:,int(shape[1]/2):,:],path1)
    #%%
    perpendicularLines2,strengthValue2,resampledImg2,convolve2dimage1st2,convolve2dimage2st2 = qca.edgeStrength(gray_img,proximalPath+distalPath2,20,40)
    shape=strengthValue2.shape
    path2 = qca.dynamic_programming(strengthValue2[:,0:int(shape[1]/2),0])
    countour2=qca.mapCountour2img(strengthValue2[:,0:int(shape[1]/2),:],path2)

    perpendicularLines3,strengthValue3,resampledImg3,convolve2dimage1st3,convolve2dimage2st3 = qca.edgeStrength(gray_img,distalPath2[::-1]+distalPath1,20,40)
    shape=strengthValue2.shape
    path3 = qca.dynamic_programming(strengthValue3[:,0:int(shape[1]/2),0])
    countour3=qca.mapCountour2img(strengthValue3[:,0:int(shape[1]/2),:],path3)
    points=[]
    for p in countour1[::smoothStep]:
        points.append(PointD(p[0],p[1]))
    points.append(PointD(countour1[-1][0],countour1[-1][1]))
    smoothed_points = chaikin_smoothing(points, tension=0.5, nr_of_iterations=3)

    points=[]
    for p in countour2[::smoothStep]:
        points.append(PointD(p[0],p[1]))
    points.append(PointD(countour2[-1][0],countour2[-1][1]))
    smoothed_points2 = chaikin_smoothing(points, tension=0.5, nr_of_iterations=3)
    
    points=[]
    for p in countour3[::smoothStep]:
        points.append(PointD(p[0],p[1]))
    points.append(PointD(countour3[-1][0],countour3[-1][1]))
    smoothed_points3 = chaikin_smoothing(points, tension=0.5, nr_of_iterations=3)
    pltLines(perpendicularLines2,[smoothed_points,smoothed_points2,smoothed_points3],gray_img)

    #%%

    pltLines(None,[smoothed_points,smoothed_points2,smoothed_points3],gray_img)
# %%
